var UserProxy = {
    sms_auth:function (country, phone, target, selector, failureSelector) {
        var dict = NetPack.create("user_sms_auth");
        dict["country"] = country;
        dict["phone"] = phone;
        var net = new NetUtil();
        net.postMsg(dict, target, selector, true, failureSelector);
    },
    signup:function (country, phone, password, sms_code, invitation_code, target, selector, failureSelector) {
        var dict = NetPack.create("user_signup");
        dict["country"] = country;
        dict["phone"] = phone;
        dict["password"] = password;
        dict["sms_code"] = sms_code;
        dict["invitation_code"] = invitation_code;
        var net = new NetUtil();
        net.postMsg(dict, target, selector, true, failureSelector);
    },
    login:function (country, phone, password, gcode, target, selector, failureSelector) {
        var dict = NetPack.create("user_login");
        dict["country"] = country;
        dict["phone"] = phone;
        dict["password"] = password;
        dict["gcode"] = gcode;
        var net = new NetUtil();
        net.postMsg(dict, target, selector, true, failureSelector);
    },
    password_update:function (country, phone, password, sms_code, target, selector, failureSelector) {
        var dict = NetPack.create("user_password_update");
        dict["country"] = country;
        dict["phone"] = phone;
        dict["password"] = password;
        dict["sms_code"] = sms_code;
        var net = new NetUtil();
        net.postMsg(dict, target, selector, true, failureSelector);
    },
    invitation:function (target, selector, failureSelector) {
        var dict = NetPack.create("invitation_info");
        var net = new NetUtil();
        net.postMsg(dict, target, selector, true, failureSelector);
    },
    googauth_info:function (target, selector, failureSelector) {
        var dict = NetPack.create("user_googauth_info");
        var net = new NetUtil();
        net.postMsg(dict, target, selector, true, failureSelector);
    },
    googauth_open:function (gcode, idcard, target, selector, failureSelector) {
        var dict = NetPack.create("user_googauth_open");
        dict["gcode"] = gcode;
        dict["idcard"] = idcard;
        var net = new NetUtil();
        net.postMsg(dict, target, selector, true, failureSelector);
    },
    googauth_close:function (gcode, target, selector, failureSelector) {
        var dict = NetPack.create("user_googauth_close");
        dict["gcode"] = gcode;
        var net = new NetUtil();
        net.postMsg(dict, target, selector, true, failureSelector);
    }
};
var Wallet = {
    info:function (target, selector, failureSelector) {
        var dict = NetPack.create("wallet_info");
        var net = new NetUtil();
        net.postMsg(dict, target, selector, true, failureSelector);
    },
    recharge_addr:function (target, selector, failureSelector) {
        var dict = NetPack.create("wallet_recharge_addr");
        var net = new NetUtil();
        net.postMsg(dict, target, selector, true, failureSelector);
    },
    withdraw_sms_auth : function (target, selector, failureSelector) {
        var dict = NetPack.create("wallet_withdraw_sms_auth");
        var net = new NetUtil();
        net.postMsg(dict, target, selector, true, failureSelector);
    },
    withdraw:function (coin, addr, volume, sms_code, target, selector, failureSelector) {
        var dict = NetPack.create("wallet_withdraw");
        dict["coin"] = coin;
        dict["addr"] = addr;
        dict["volume"] = volume;
        dict["sms_code"] = sms_code;
        var net = new NetUtil();
        net.postMsg(dict, target, selector, true, failureSelector);
    },
    recharge_record:function (limit, target, selector, failureSelector) {
        var dict = NetPack.create("wallet_recharge_record");
        dict["limit"] = limit;
        var net = new NetUtil();
        net.postMsg(dict, target, selector, true, failureSelector);
    },
    withdraw_record:function (limit, target, selector, failureSelector) {
        var dict = NetPack.create("wallet_withdraw_record");
        dict["limit"] = limit;
        var net = new NetUtil();
        net.postMsg(dict, target, selector, true, failureSelector);
    },
    detailed_list:function (coin, type, direction, limit, target, selector, failureSelector) {
        var dict = NetPack.create("wallet_detailed_list");
        dict["coin"] = coin;
        dict["type"] = type;
        dict["direction"] = direction;
        dict["limit"] = limit;
        var net = new NetUtil();
        net.postMsg(dict, target, selector, true, failureSelector);
    }
};
var Exchange = {
    info:function (target, selector, failureSelector) {
        var dict = NetPack.create("exchange_info");
        var net = new NetUtil();
        net.postMsg(dict, target, selector, false, failureSelector);
    },
    info_loading:function (target, selector, failureSelector) {
        var dict = NetPack.create("exchange_info");
        var net = new NetUtil();
        net.postMsg(dict, target, selector, true, failureSelector);
    },
    create_buy_order:function (price, volume, target, selector, failureSelector) {
        var dict = NetPack.create("exchange_create_buy_order");
        if (price <= 0) {
            dict["market"] = 1;
        } else {
            dict["price"] = price;
        }
        dict["volume"] = volume;
        var net = new NetUtil();
        net.postMsg(dict, target, selector, true, failureSelector);
    },
    create_sell_order:function (price, volume, target, selector, failureSelector) {
        var dict = NetPack.create("exchange_create_sell_order");
        if (price <= 0) {
            dict["market"] = 1;
        } else {
            dict["price"] = price;
        }
        dict["volume"] = volume;

        var net = new NetUtil();
        net.postMsg(dict, target, selector, true, failureSelector);
    },
    cancel_order:function (order_id, target, selector, failureSelector) {
        var dict = NetPack.create("exchange_cancel_order");
        dict["order_id"] = order_id;
        var net = new NetUtil();
        net.postMsg(dict, target, selector, true, failureSelector);
    },
    record:function (target, selector, failureSelector) {
        var dict = NetPack.create("exchange_record");
        var net = new NetUtil();
        net.postMsg(dict, target, selector, true, failureSelector);
    },
    my_order:function (target, selector, failureSelector) {
        var dict = NetPack.create("exchange_my_order");
        var net = new NetUtil();
        net.postMsg(dict, target, selector, true, failureSelector);
    }
};
var Asset = {
    fishbowl_list:function (target, selector, failureSelector) {
        var dict = NetPack.create("asset_fishbowl_list");
        var net = new NetUtil();
        net.postMsg(dict, target, selector, true, failureSelector);
    },
    fish_list:function (target, selector, failureSelector) {
        var dict = NetPack.create("asset_fish_list");
        var net = new NetUtil();
        net.postMsg(dict, target, selector, true, failureSelector);
    }
}
var Auction = {
    info:function (target, selector, failureSelector) {
        var dict = NetPack.create("auction_info");
        var net = new NetUtil();
        net.postMsg(dict, target, selector, true, failureSelector);
    },
    bid:function (price, number, target, selector, failureSelector) {
        var dict = NetPack.create("auction_bid");
        dict["price"] = price;
        dict["number"] = number;
        var net = new NetUtil();
        net.postMsg(dict, target, selector, true, failureSelector);
    }
};
var Auction_Fish = {
    info:function (target, selector, failureSelector) {
        var dict = NetPack.create("auction_info");
        dict["item"] = "fish";
        var net = new NetUtil();
        net.postMsg(dict, target, selector, true, failureSelector);
    },
    bid:function (price, number, target, selector, failureSelector) {
        var dict = NetPack.create("auction_bid");
        dict["item"] = "fish";
        dict["price"] = price;
        dict["number"] = number;
        var net = new NetUtil();
        net.postMsg(dict, target, selector, true, failureSelector);
    }
};
var Buying = {
    info:function (target, selector, failureSelector) {
        var dict = NetPack.create("buying_info");
        var net = new NetUtil();
        net.postMsg(dict, target, selector, true, failureSelector);
    },
    buy:function (target, selector, failureSelector) {
        var dict = NetPack.create("buying_buy");
        var net = new NetUtil();
        net.postMsg(dict, target, selector, true, failureSelector);
    }
};
var Buying_Fish = {
    info:function (target, selector, failureSelector) {
        var dict = NetPack.create("buying_info");
        dict["item"] = "fish";
        var net = new NetUtil();
        net.postMsg(dict, target, selector, true, failureSelector);
    },
    buy:function (target, selector, failureSelector) {
        var dict = NetPack.create("buying_buy");
        dict["item"] = "fish";
        var net = new NetUtil();
        net.postMsg(dict, target, selector, true, failureSelector);
    }
};
var Auction_Fish = {
    info:function (target, selector, failureSelector) {
        var dict = NetPack.create("auction_info");
        dict["item"] = "fish";
        var net = new NetUtil();
        net.postMsg(dict, target, selector, true, failureSelector);
    },
    bid:function (price, number, target, selector, failureSelector) {
        var dict = NetPack.create("auction_bid");
        dict["price"] = price;
        dict["number"] = number;
        dict["item"] = "fish";
        var net = new NetUtil();
        net.postMsg(dict, target, selector, true, failureSelector);
    }
};
var Buying_Fish = {
    info:function (target, selector, failureSelector) {
        var dict = NetPack.create("buying_info");
        dict["item"] = "fish";
        var net = new NetUtil();
        net.postMsg(dict, target, selector, true, failureSelector);
    },
    buy:function (target, selector, failureSelector) {
        var dict = NetPack.create("buying_buy");
        dict["item"] = "fish";
        var net = new NetUtil();
        net.postMsg(dict, target, selector, true, failureSelector);
    }
};
var Invitation = {
    info:function (target, selector, failureSelector) {
        var dict = NetPack.create("invitation_info");
        var net = new NetUtil();
        net.postMsg(dict, target, selector, true, failureSelector);
    },
    vip_code:function (code, target, selector, failureSelector) {
        var dict = NetPack.create("invitation_vip_code");
        dict["code"] = code;
        var net = new NetUtil();
        net.postMsg(dict, target, selector, true, failureSelector);
    }
};
var Currency = {
    info:function (target, selector, failureSelector) {
        var dict = NetPack.create("currency_info");
        var net = new NetUtil();
        net.postMsg(dict, target, selector, true, failureSelector);
    },
    exchange:function (fishcoin, target, selector, failureSelector) {
        var dict = NetPack.create("currency_exchange");
        dict["fishcoin"] = fishcoin;
        var net = new NetUtil();
        net.postMsg(dict, target, selector, true, failureSelector);
    }
};
var Candy = {
    info:function (target, selector, failureSelector) {
        var dict = NetPack.create("candy_info");
        var net = new NetUtil();
        net.postMsg(dict, target, selector, true, failureSelector);
    },
    addr:function (addr, target, selector, failureSelector) {
        var dict = NetPack.create("candy_addr");
        dict["addr"] = addr;
        var net = new NetUtil();
        net.postMsg(dict, target, selector, true, failureSelector);
    }
};
var Roulette = {
    info:function (target, selector, failureSelector) {
        var dict = NetPack.create("roulette_info");
        var net = new NetUtil();
        net.postMsg(dict, target, selector, true, failureSelector);
    },
    turn:function (multiple, target, selector, failureSelector) {
        var dict = NetPack.create("roulette_turn");
        var net = new NetUtil();
        dict["multiple"] = multiple;
        net.postMsg(dict, target, selector, true, failureSelector);
    }
};
var Market = {
    info_item:function (item, min_price, max_price, page, order_type, order_by, target, selector, failureSelector) {
        var dict = NetPack.create("market_info");
        var net = new NetUtil();
        dict["item"] = item;
        dict["page"] = page;
        dict["min_price"] = min_price;
        dict["max_price"] = max_price;
        dict["order_type"] = order_type;
        dict["order_by"] = order_by;
        net.postMsg(dict, target, selector, false, failureSelector);
    },
    info_loading_item:function (item, min_price, max_price, page, order_type, order_by, target, selector, failureSelector) {
        var dict = NetPack.create("market_info");
        var net = new NetUtil();
        dict["item"] = item;
        dict["page"] = page;
        dict["min_price"] = min_price;
        dict["max_price"] = max_price;
        dict["order_type"] = order_type;
        dict["order_by"] = order_by;
        net.postMsg(dict, target, selector, true, failureSelector);
    },
    info:function (page, order_type, order_by, target, selector, failureSelector) {
        var dict = NetPack.create("market_info");
        var net = new NetUtil();
        dict["page"] = page;
        dict["order_type"] = order_type;
        dict["order_by"] = order_by;
        net.postMsg(dict, target, selector, false, failureSelector);
    },
    info_loading:function (page, order_type, order_by, target, selector, failureSelector) {
        var dict = NetPack.create("market_info");
        var net = new NetUtil();
        dict["page"] = page;
        dict["order_type"] = order_type;
        dict["order_by"] = order_by;
        net.postMsg(dict, target, selector, true, failureSelector);
    },
    sell:function (number, price, target, selector, failureSelector) {
        var dict = NetPack.create("market_sell");
        var net = new NetUtil();
        dict["number"] = number;
        dict["price"] = price;
        net.postMsg(dict, target, selector, true, failureSelector);
    },
    sell_cancel:function (order_id, target, selector, failureSelector) {
        var dict = NetPack.create("market_sell_cancel");
        var net = new NetUtil();
        dict["order_id"] = order_id;
        net.postMsg(dict, target, selector, true, failureSelector);
    },
    buy:function (order_id, target, selector, failureSelector) {
        var dict = NetPack.create("market_buy");
        var net = new NetUtil();
        dict["order_id"] = order_id;
        net.postMsg(dict, target, selector, true, failureSelector);
    },
    log:function (page, target, selector, failureSelector) {
        var dict = NetPack.create("market_log");
        var net = new NetUtil();
        dict["page"] = page;
        net.postMsg(dict, target, selector, false, failureSelector);
    },
    log_loading:function (page, target, selector, failureSelector) {
        var dict = NetPack.create("market_log");
        var net = new NetUtil();
        dict["page"] = page;
        net.postMsg(dict, target, selector, true, failureSelector);
    },
    trade_log:function (target, selector, failureSelector) {
        var dict = NetPack.create("market_trade_log");
        var net = new NetUtil();
        net.postMsg(dict, target, selector, false, failureSelector);
    },
    leaderboard:function (target, selector, failureSelector) {
        var dict = NetPack.create("market_leaderboard");
        var net = new NetUtil();
        net.postMsg(dict, target, selector, false, failureSelector);
    }
};
var Market_Fish = {
    info:function (page, order_type, order_by, target, selector, failureSelector) {
        var dict = NetPack.create("market_info");
        var net = new NetUtil();
        dict["page"] = page;
        dict["order_type"] = order_type;
        dict["order_by"] = order_by;
        dict["item"] = "fish";
        net.postMsg(dict, target, selector, false, failureSelector);
    },
    info_loading:function (page, order_type, order_by, target, selector, failureSelector) {
        var dict = NetPack.create("market_info");
        var net = new NetUtil();
        dict["page"] = page;
        dict["order_type"] = order_type;
        dict["order_by"] = order_by;
        dict["item"] = "fish";
        net.postMsg(dict, target, selector, true, failureSelector);
    },
    sell:function (number, price, target, selector, failureSelector) {
        var dict = NetPack.create("market_sell");
        var net = new NetUtil();
        dict["number"] = number;
        dict["price"] = price;
        dict["item"] = "fish";
        net.postMsg(dict, target, selector, true, failureSelector);
    },
    sell_cancel:function (order_id, target, selector, failureSelector) {
        var dict = NetPack.create("market_sell_cancel");
        var net = new NetUtil();
        dict["order_id"] = order_id;
        net.postMsg(dict, target, selector, true, failureSelector);
    },
    buy:function (order_id, target, selector, failureSelector) {
        var dict = NetPack.create("market_buy");
        var net = new NetUtil();
        dict["order_id"] = order_id;
        net.postMsg(dict, target, selector, true, failureSelector);
    },
    log:function (page, target, selector, failureSelector) {
        var dict = NetPack.create("market_log");
        var net = new NetUtil();
        dict["page"] = page;
        dict["item"] = "fish";
        net.postMsg(dict, target, selector, false, failureSelector);
    },
    log_loading:function (page, target, selector, failureSelector) {
        var dict = NetPack.create("market_log");
        var net = new NetUtil();
        dict["page"] = page;
        dict["item"] = "fish";
        net.postMsg(dict, target, selector, true, failureSelector);
    },
    trade_log:function (target, selector, failureSelector) {
        var dict = NetPack.create("market_trade_log");
        var net = new NetUtil();
        net.postMsg(dict, target, selector, false, failureSelector);
    },
    leaderboard:function (target, selector, failureSelector) {
        var dict = NetPack.create("market_leaderboard");
        var net = new NetUtil();
        dict["item"] = "fish";
        net.postMsg(dict, target, selector, false, failureSelector);
    }
};
var Fishpond = {
    info:function (target, selector, failureSelector) {
        var dict = NetPack.create("fishpond_info");
        var net = new NetUtil();
        net.postMsg(dict, target, selector, true, failureSelector);
    },
    update:function (numbers, target, selector, failureSelector) {
        var dict = NetPack.create("fishpond_update");
        dict["numbers"] = numbers;
        var net = new NetUtil();
        net.postMsg(dict, target, selector, true, failureSelector);
    }
};
var Share = {
    fishpond:function (user, target, selector, failureSelector) {
        var dict = NetPack.create("share_fishpond");
        dict["user"] = user;
        var net = new NetUtil();
        net.postMsg(dict, target, selector, true, failureSelector);
    }
}
var ApiProxy = {
    my_account:function (target, selector, failureSelector) {
        var dict = NetPack.create("my_account");
        var net = new NetUtil();
        net.postMsg(dict, target, selector, true, failureSelector);
    },
    fishbowl_auction:function (target, selector, failureSelector) {
        var dict = NetPack.create("fishbowl_auction");
        var net = new NetUtil();
        net.postMsg(dict, target, selector, false, failureSelector);
    },
    fishbowl_auction_loading:function (target, selector, failureSelector) {
        var dict = NetPack.create("fishbowl_auction");
        var net = new NetUtil();
        net.postMsg(dict, target, selector, true, failureSelector);
    },
    fishbowl_buying:function (target, selector, failureSelector) {
        var dict = NetPack.create("fishbowl_buying");
        var net = new NetUtil();
        net.postMsg(dict, target, selector, false, failureSelector);
    },
    fishbowl_buying_loading:function (target, selector, failureSelector) {
        var dict = NetPack.create("fishbowl_buying");
        var net = new NetUtil();
        net.postMsg(dict, target, selector, true, failureSelector);
    },
    fish_auction:function (target, selector, failureSelector) {
        var dict = NetPack.create("fish_auction");
        var net = new NetUtil();
        net.postMsg(dict, target, selector, false, failureSelector);
    },
    fish_auction_loading:function (target, selector, failureSelector) {
        var dict = NetPack.create("fish_auction");
        var net = new NetUtil();
        net.postMsg(dict, target, selector, true, failureSelector);
    },
    fish_buying:function (target, selector, failureSelector) {
        var dict = NetPack.create("fish_buying");
        var net = new NetUtil();
        net.postMsg(dict, target, selector, false, failureSelector);
    },
    fish_buying_loading:function (target, selector, failureSelector) {
        var dict = NetPack.create("fish_buying");
        var net = new NetUtil();
        net.postMsg(dict, target, selector, true, failureSelector);
    }
};
function getSid() {
    if (localStorage) {
        return localStorage._sid;
    } else {
        return getCookie("_sid");
    }
}
function getVer() {
    var ver;
    if (localStorage) {
        ver = localStorage._ver;
    } else {
        ver = getCookie("_ver");
    }
    if (ver == null || ver == undefined || ver == "undefined") {
        return "1.0";
    } else {
        return ver;
    }
}
function getKey() {
    if (localStorage) {
        return localStorage._key;
    } else {
        return getCookie("_key");
    }
}
function getUid() {
    if (localStorage) {
        return localStorage._uid;
    } else {
        return getCookie("_uid");
    }
}
var _oriHostUrl = "http://test001.fishchain.io/fishapi/";
var _hostUrl = _oriHostUrl;
function getHostUrl() {
    //return "http://13.230.49.231/fishapi/";
    //return "https://play.fishchain.io/fishapi/";
    if (login_sha256_enable) {
        return "https://play.fishchain.io/fishapi/";
    }
    return _hostUrl;
}
function setHostUrl(hostUrl) {
    _hostUrl = hostUrl;
}
function resetHostUrl() {
    _hostUrl = _oriHostUrl;
}
function getWebSocketUrl() {
    return "ws://test001.fishchain.io/fishws/";
}
var NetPack = {
    create:function(cmd){
        var dict = [];
        dict["sid"] = getSid();
        dict["ver"] = getVer();
        dict["ts"] = new Date().getTime();
        dict["lang"] = getLang();
        dict["cmd"] = cmd;
        return dict;
    }
};
var NetUtil = function () {
    this.m_Selector = null;
    this.m_FailureSelector = null;
    this.m_IsShowLoading = true;
    this.m_Dict = null;
    this.m_Request = null;
    this.m_Target = null;
    this.postMsg = function(dict, target, selector, isLoading, failureSeletor) {
        if (getSid() == null || getSid() == undefined || getSid() == "") {
            //location.href = "login.html";
        }
        this.m_Target = target;
        if (selector) {
            this.m_Selector = selector.bind(target);
        }
        this.m_Dict = dict;
        if (isLoading == null || isLoading == undefined) {
            isLoading = true;
        }
        this.m_IsShowLoading = isLoading;
        if (failureSeletor) {
            this.m_FailureSelector = failureSeletor.bind(target);
        }
        this.post();
    };
    this.post = function() {
        if (this.m_IsShowLoading) {
            showLoading();
        }
        var net = this;
        var msg = this.translateFromDict(this.m_Dict);
        var sign = sha256(msg + getKey());
        msg += "sig=" + sign;
        if (this.m_Dict["cmd"] != null && this.m_Dict["cmd"] != "") {
            $(document).unbind(this.m_Dict["cmd"]).bind(this.m_Dict["cmd"], function (e, data) {
                net.m_Selector(this, data);
            });
        }
        $.post(getHostUrl(), msg, function(data) {
            hideLoading();
            Data.callback(data);
            extendData(data);
            if (net.validate(data)) {
                if (net.m_Selector) {
                    net.m_Selector(net.m_Target, data, net);
                }
            }
        }).fail(function(a,b,c){
            hideLoading();
        });
    };
    this.showLoading = function(){};
    this.hideLoading = function(){};
    this.jsonNullCallback = function(){};
    this.netCanNotReachCallback = function(){};
    this.successCallback = function(ret){};
    this.failureCallback = function(ret){};
    this.translateFromDict = function(dict) {
        var msg = "";
        var array = [];
        for (var key in dict) {
            array.push(key);
        }
        array.sort();
        for (var key in array) {
            msg += this.addUnitAsString(dict, array[key]);
        }
        for (var key in dict) {
            //msg += this.addUnitAsString(dict, key);
        }
        return msg;
    };
    this.addUnitAsString = function(dict, key) {
        var item = dict[key];
        if (item != null) {
            return key + "=" + item + "&";
        }
        return "";
    };
    this.validate = function(json) {
        if(json == null) {
            this.jsonNullCallback();
            this.failure(json);
            return false ;
        }
        var result = json.statuscode;
        //console.log(json);
        if (json.statuscode == 403 || json.statuscode == 402) {
            clearSession();
            goLogin();
        } else if (json.statuscode != 0 && json.statuscode != 301) {
            if (json.statuscode != null) {
                showTips(json.err_msg);
            }
        }
        if(result == 0 || result == 301) {
            this.successCallback(json);
            return true;
        }
        if (this.failure(json) == false) {
            this.failureCallback(json);
        }
        return false;
    };
    this.failure = function(json) {
        if (this.m_FailureSelector) {
            this.m_FailureSelector(this.m_Target, json, this);
            return true;
        }
        return false;
    };
};
var WebSocketProxy = {
    heart : function () {
        var dict = NetPack.create("heart");
        WebSocketUtil.postMsg(dict);
    },
    request : function (json) {
        var dict = NetPack.create("subscribe");
        dict["data"] = json;
        WebSocketUtil.postMsg(dict);
    },
    auction:function (target, selector, failureSelector) {
        var json = {};
        json.auction = null;
        WebSocketProxy.request(JSON.stringify(json));
        $(document).unbind("update").bind("update", function (e, data) {
            selector(this, data);
        });
    },
    auction_loading:function (target, selector, failureSelector) {
        var json = {};
        json.auction = null;
        WebSocketProxy.request(JSON.stringify(json));
        $(document).unbind("update").bind("update", function (e, data) {
            selector(this, data);
        });
    },
    buying:function (target, selector, failureSelector) {
        var json = {};
        json.buying = null;
        WebSocketProxy.request(JSON.stringify(json));
        $(document).unbind("update").bind("update", function (e, data) {
            selector(this, data);
        });
    },
    buying_loading:function (target, selector, failureSelector) {
        var json = {};
        json.buying = null;
        json.roulette = null;
        WebSocketProxy.request(JSON.stringify(json));
        $(document).unbind("update").bind("update", function (e, data) {
            selector(this, data);
        });
    },
    exchange_info:function (target, selector, failureSelector) {
        var json = {};
        json.exchange = null;
        json.wallet = null;
        WebSocketProxy.request(JSON.stringify(json));
        $(document).unbind("update").bind("update", function (e, data) {
            selector(this, data);
        });
    },
    wallet:function (target, selector, failureSelector) {
        var json = {};
        json.wallet = null;
        WebSocketProxy.request(JSON.stringify(json));
        $(document).unbind("update").bind("update", function (e, data) {
            selector(this, data);
        });
    }
};
var WebSocketUtil = {
    socket : null,
    queue : [],
    forceClose : false,
    heart : 0,
    init : function() {
        if (this.socket) {
            return;
        }
        this.socket = new ReconnectingWebSocket(getWebSocketUrl());
        this.socket.onopen = function(evt) {
            while (WebSocketUtil.queue.length > 0) {
                WebSocketUtil.send(WebSocketUtil.queue.shift());
            }
        };

        this.socket.onmessage = function(evt) {
            //console.log(evt.data);
            var data = eval("("+evt.data+")");
            if (data.statuscode) {
                if (data.statuscode == 901) {
                    showMessageBox($.i18n.prop("message_websocket_another_login"), function () {
                        goLogin();
                    });
                    $("#messagebox_html_close").hide();
                    WebSocketUtil.close();
                    return;
                }
            }
            Data.callback(data);
            extendData(data);
            $(document).trigger("update", data);
            if (data.statuscode != null) {
                if (data.statuscode != 0 && data.statuscode != 301) {
                    showTips(data.err_msg);
                } else {
                    if (data.cmd != null && data.cmd != "") {
                        $(document).trigger(data.cmd, data);
                    }
                }
            }
        };

        this.socket.onerror = function(evt) {
            console.log('Network onerror...' + evt);
        };

        this.socket.onclose = function(evt) {
            if (WebSocketUtil.forceClose == false) {
                WebSocketUtil.init();
            }
        };
        if (WebSocketUtil.heart != 0) {
            clearInterval(WebSocketUtil.heart);
        }
        WebSocketUtil.heart = setInterval(function () {
            WebSocketProxy.heart();
        }, 20000);
    },
    postMsg : function (dict) {
        var msg = this.translateFromDict(dict);
        var sign = sha256(msg + getKey());
        msg += "sig=" + sign;
        this.send(msg);
    },
    message : function(data) {
        var msg = this.tag + " received " + data;
    },
    send : function(msg) {
        if(this.socket != null && this.socket.readyState == WebSocket.OPEN) {
            this.socket.send(msg);
        } else {
            if (this.queue.length > 10) {
                this.queue.shift();
            }
            this.queue.push(msg);
            this.init();
        }
    },
    translateFromDict : function(dict) {
        var msg = "";
        var array = [];
        for (var key in dict) {
            array.push(key);
        }
        array.sort();
        for (var key in array) {
            msg += this.addUnitAsString(dict, array[key]);
        }
        for (var key in dict) {
            //msg += this.addUnitAsString(dict, key);
        }
        return msg;
    },
    addUnitAsString : function(dict, key) {
        var item = dict[key];
        if (item != null) {
            return key + "=" + item + "&";
        }
        return "";
    },
    close : function () {
        if (WebSocketUtil.heart != 0) {
            clearInterval(WebSocketUtil.heart);
        }
        this.forceClose = true;
        this.socket.close();
    },
    refresh : function () {
        this.forceClose = true;
        this.socket.refresh();
    }
};